package com.suke.czx.modules.income.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.suke.czx.common.utils.FieldConstant;
import com.suke.czx.common.utils.ListUtil;
import com.suke.czx.common.utils.R;
import com.suke.czx.modules.income.entity.Income;
import com.suke.czx.modules.income.entity.IncomeSearchBo;
import com.suke.czx.modules.income.mapper.IncomeMapper;
import com.suke.czx.modules.income.service.IncomeService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 应用模块名称: 收支
 * 代码描述: 收支业务层
 * copyright: AUZAR ALL RIGHTS RESERVED
 * company: AUZAR
 *
 * @author: 颜米晨
 * @date: 2021/09/09 10:49:31
 */
@Slf4j
@Service
@AllArgsConstructor
public class IncomeServiceImpl extends ServiceImpl<IncomeMapper, Income> implements IncomeService {

    private final IncomeMapper incomeMapper;

    /**
     * 分页查询收支列表
     * @param incomeSearchBo 查询BO
     * @return VO
     */
    @Override
    public R pageIncomeList(IncomeSearchBo incomeSearchBo) {
        // 获取计划收支总记录数
        Integer count = incomeMapper.countParentIncome(incomeSearchBo);
        // 获取计划收支查询结果集
        List<Income> parentList = incomeMapper.pageParentIncomeList(incomeSearchBo, (incomeSearchBo.getPage() - 1) * incomeSearchBo.getLimit(), incomeSearchBo.getLimit());
        if (ListUtil.isEmpty(parentList)) {
            log.warn("计划收支为空");
            return R.ok();
        }
        // 获取实际收支查询结果集
        List<Income> childrenList = incomeMapper.childrenIncomeList(parentList.stream().map(Income::getIncomeId).collect(Collectors.toList()));
        // 将实际收支加入计划收支数据集
        parentList.addAll(childrenList);
        // 将实际收支记录集按照对应的计划收支id归集数据
        Map<Long, List<Income>> childrenMap = parentList.stream().filter(i -> !StrUtil.isBlankIfStr(i.getParentId()))
                .collect(Collectors.groupingBy(Income::getParentId, HashMap::new, Collectors.toList()));
        // 分组处理数据集
        List<Income> dataList = parentList.stream().filter(i -> StrUtil.isBlankIfStr(i.getParentId()))
                .peek(i -> i.setChildren(childrenMap.get(i.getIncomeId()))).collect(Collectors.toList());
        // 返回结果
        return Objects.requireNonNull(R.ok().put(FieldConstant.TOTAL, count)).setData(dataList);
    }

    /**
     * 删除收支
     * @param incomeId 收支编码
     * @param userId 操作者编码
     * @return VO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R updateDelIncome(Long incomeId, Long userId) {
        // 校验该收支是否为存在实际收支的计划收支
        Integer count = incomeMapper.getIfHasChildrenIncome(incomeId);
        if (count != null && count > 0) {
            return R.error("该计划收支存在实际收支记录,否则请先删除其关联实际收支");
        }
        // 逻辑删除收支
        incomeMapper.updateDelIncome(incomeId, userId);
        return R.ok();
    }

}
